package org.setec.config;

import org.setec.utils.xml.XMLUtils;

import java.util.*;

public class XMLNode {

    private String name;
    private Map attributes;
    private Map children = new HashMap();

    public XMLNode(String content) {

        content = XMLUtils.normalizeXML(content);

        name = XMLUtils.findFirst(content, "<[a-zA-Z0-9]+[ |/>]").replaceAll("<", "").replaceAll("/>$|>$", "").trim();

        String attributeContent = "";
        String internalContent = "";
        if (XMLUtils.findFirst(content, "<" + name + "[^>]*/>") != null) {
            attributeContent = XMLUtils.findFirst(content, "<" + name + "[^<^>]*/>").replaceAll("<" + name, "").
                    replaceAll("/>", "").trim();
        } else {
            attributeContent = XMLUtils.findFirst(content, "<" + name + "[^<^>]*>").replaceAll("<" + name, "").
                    replaceAll(">", "").trim();
            internalContent = content.replaceAll("<" + name + "[^<^>]*>", "").replaceAll("</" + name + ">$", "");
        }
        attributes = XMLUtils.parseAttributes(attributeContent);


        String parsedContent = internalContent;
        while (parsedContent.length() > 0) {
            String internalNodeName = XMLUtils.findFirst(parsedContent, "<[a-zA-Z0-9]+[ |/>]").replaceAll("<", "").replaceAll("/>$|>$", "").trim();
            String internalNodeBlock = null;
            if (XMLUtils.findFirst(content, "<" + internalNodeName + "[^>^>]*/>") != null) {
                internalNodeBlock = XMLUtils.findFirst(parsedContent, "<" + internalNodeName + "[^>]*/>");
            } else {
                internalNodeBlock = XMLUtils.findFirst(parsedContent, "<" + internalNodeName + ".*</" + internalNodeName + ">");
            }

            XMLNode child = new XMLNode(internalNodeBlock);

            if (children.get(child.getName()) == null) {
                children.put(child.getName(), new ArrayList());
            }
            ((List) children.get(child.getName())).add(child);
            parsedContent = parsedContent.substring(internalNodeBlock.length());
        }
    }

    public String getName() {
        return name;
    }

    public Map getAttributes() {
        return attributes;
    }

    public Map getChildren() {
        return children;
    }

    public XMLNode getChildNode(String name, int index) {
        return (XMLNode) ((List) children.get(name)).get(index);
    }

    public int getChildNumber(String name) {
        if (children.get(name) == null) {
            return 0;
        }
        return ((List) children.get(name)).size();
    }

    public String getAttribute(String name) {
        return (String) attributes.get(name);
    }
}
